package com.eleaf.adbb.template;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import com.eleaf.adbb.util.BaseUtil;

public class MethodTemplate {

	private String modifiers, returnType, methodName;
	private String code = "\n";
	private String annotation = "\n";
	private String retunCode;

	private List<String> parameters;
	private List<String> packages;

	/**
	 * 初始化函数模版
	 * 
	 * @param modifiers 修饰符
	 * @param returnType 返回类型
	 * @param methodName 函数名
	 * @param parameters 参数类型
	 * @param packages 所用到的包
	 */
	public MethodTemplate( int modifiers, String returnType, String methodName, List<String> parameters, List<String> packages ) {
		this.modifiers = Modifier.toString ( modifiers );
		this.returnType = returnType;
		this.methodName = methodName;
		this.parameters = parameters;
		this.packages = packages;
	}

	/**
	 * 
	 * @param method 方法
	 */
	public MethodTemplate( Method method ) {
		this.modifiers = Modifier.toString ( method.getModifiers () );
		this.methodName = method.getName ();
		parameters = new ArrayList<String> ();
		packages = new ArrayList<String> ();

		Class<?>[] parameterTypes = method.getParameterTypes ();
		for ( Class<?> parameterType : parameterTypes ) {
			parameters.add ( parameterType.getSimpleName () );
			parsingPackage ( parameterType );
		}

		Class<?> returnTypeCls = method.getReturnType ();
		this.returnType = returnTypeCls.getSimpleName ();
		parsingPackage ( returnTypeCls );
	}

	/**
	 * 插入函数体代码
	 * 
	 * @param lines
	 */
	public void insertCode( String... lines ) {
		for ( String str : lines ) {
			code = BaseUtil.appendString ( code, str, "\n" );
		}
	}

	/**
	 * 添加Annotation
	 * 
	 * @param annotations
	 */
	public void addAnnotation( String... annotations ) {
		for ( String line : annotations ) {
			annotation = BaseUtil.appendString ( annotation, line, "\n" );
		}
	}

	/**
	 * 设置return内容，默认为null
	 * 
	 * @param retunCode
	 */
	public void setRetunCode( String retunCode ) {
		if ( retunCode != null && !retunCode.isEmpty () )
			this.retunCode = BaseUtil.appendString ( retunCode.lastIndexOf ( "return" ) == -1 ? "return " : "", retunCode, retunCode.lastIndexOf ( ";" ) == -1 ? ";" : "" );
	}

	/**
	 * 获取参数名
	 * 
	 * @param index
	 * @return
	 */
	public String getParameterName( int index ) {
		return BaseUtil.appendString ( "arg", String.valueOf ( index ) );
	}

	private void parsingPackage( Class<?> cls ) {
		if ( !cls.isPrimitive () ) {
			if ( cls.isArray () ) {
				if ( !cls.getComponentType ().isPrimitive () ) {
					packages.add ( cls.getComponentType ().getCanonicalName () );
				}
				return;
			}
			packages.add ( cls.getCanonicalName () );
		}

	}

	@Override
	public String toString() {
		modifiers = modifiers.replace ( "abstract", "" );
		StringBuffer sb = new StringBuffer ();
		for ( int i = 0; i < parameters.size (); i++ ) {
			sb.append ( "," ).append ( parameters.get ( i ) ).append ( " " ).append ( "arg" ).append ( i );
		}
		if ( sb.length () > 0 )
			sb.delete ( 0, 1 );
		if ( retunCode == null || retunCode.trim ().isEmpty () )
			if ( "void".equals ( returnType.trim () ) )
				retunCode = "";
			else
				retunCode = "return null;";
		return BaseUtil.appendString ( annotation, modifiers, " ", returnType, " ", methodName, "(", sb.toString (), "){", code, retunCode, "}" );
	}

	/**
	 * 获取该方法所有用到的包引用
	 * 
	 * @return
	 */
	public List<String> getPackages() {
		return packages;
	}

}
